package attr

import (
	"context"
	"mall/common/excption"
	constans "mall/services/product/rpc/consts"
	"mall/services/product/rpc/internal/domain/bo"
	"mall/services/product/rpc/internal/domain/do"
	"mall/services/product/rpc/internal/mapper"
	"mall/services/product/rpc/internal/mapper/entity"

	"mall/services/product/rpc/internal/svc"
	"mall/services/product/rpc/pb"

	"github.com/zeromicro/go-zero/core/logx"
)

type InfoLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewAttrInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *InfoLogic {
	return &InfoLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *InfoLogic) AttrInfo(in *pb.AttrInfoDTO) (*pb.AttrInfoVO, error) {
	// 1.check request dto
	attrEntity, checkErr := l.checkRequestDTO(in)
	if checkErr != nil {
		return nil, checkErr
	}
	// 2.query attr info
	categoryEntity, attrValueArr, queryErr := l.queryAttrInfo(in)
	if queryErr != nil {
		return nil, queryErr
	}
	// 3.return obj
	vo := l.packageObject(attrEntity, categoryEntity, attrValueArr)
	return vo, nil
}

func (l *InfoLogic) queryAttrInfo(in *pb.AttrInfoDTO) (do.AttrCategoryDO, []entity.AttrValueEntity, error) {
	categoryMapper := mapper.NewAttrCategoryMapper(l.ctx)
	categoryEntity, err := categoryMapper.SelectCategoryByAttrId(l.svcCtx.DBEngin, in.AttrId)
	if err != nil {
		return do.AttrCategoryDO{}, nil, err
	}
	if categoryEntity.AttrCategoryId < 0 {
		return do.AttrCategoryDO{}, nil, excption.NewErrCode(constans.AttrCategoryNotExistErr)
	}
	// 3.query attr val info
	valueMapper := mapper.NewAttrValueMapper(l.ctx)
	valueBO := bo.AttrValueBO{AttrId: in.AttrId}
	attrValueArr, err := valueMapper.SelectListCtx(l.svcCtx.DBEngin, valueBO)
	if err != nil {
		return do.AttrCategoryDO{}, nil, err
	}
	return categoryEntity, attrValueArr, nil
}

func (l *InfoLogic) packageObject(attrEntity *entity.AttrEntity, categoryEntity do.AttrCategoryDO,
	attrValueArr []entity.AttrValueEntity) *pb.AttrInfoVO {
	vo := &pb.AttrInfoVO{}
	vo.AttrId = attrEntity.AttrId
	vo.CategoryId = categoryEntity.CategoryId
	vo.CategoryName = categoryEntity.Name
	vo.CreateTime = attrEntity.CreateTime.Format("2006-01-02 15:04:05")
	vo.UpdateTime = attrEntity.UpdateTime.Format("2006-01-02 15:04:05")
	vo.ShopId = attrEntity.ShopId
	vo.Name = attrEntity.Name
	vo.Desc = attrEntity.Desc
	vo.SearchType = int32(attrEntity.SearchType)
	vo.AttrType = int32(attrEntity.AttrType)
	vo.ParentId = categoryEntity.ParentId
	vo.CategoryDesc = categoryEntity.Desc
	vo.AttrCategoryId = categoryEntity.AttrCategoryId
	if len(attrValueArr) > 0 {
		var valueArr []*pb.AttrValueVO
		for _, v := range attrValueArr {
			val := new(pb.AttrValueVO)
			val.AttrValueId = v.AttrValueId
			val.Value = v.Value
			val.AttrId = v.AttrId
			valueArr = append(valueArr, val)
		}
		vo.AttrValueArr = valueArr
	}
	return vo
}

func (l *InfoLogic) checkRequestDTO(in *pb.AttrInfoDTO) (*entity.AttrEntity, error) {
	attrBO := bo.AttrBO{
		AttrId: in.AttrId,
	}
	attrMapper := mapper.NewAttrMapper(l.ctx)
	selectOneCtx, err := attrMapper.SelectOneCtx(l.svcCtx.DBEngin, attrBO)
	if err != nil {
		return nil, err
	}
	if selectOneCtx.AttrId <= 0 {
		return nil, excption.NewErrCode(constans.AttrNotExistErr)
	}
	return &selectOneCtx, nil
}
